#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Simple Joy-Con Controller CLI Visualizer
简单的 Joy-Con 手柄命令行可视化器

基于 read_joycon.py，提供更友好的终端输出格式

Author: Yinchuan Li
Date: 2025-08-02
Description: Joy-Con 手柄实时参数监控工具，支持 60Hz 刷新率
"""

from pyjoycon import JoyCon, get_R_id, get_L_id
import time
import os

def clear_screen():
    """清屏"""
    os.system('clear' if os.name == 'posix' else 'cls')

def print_header():
    """打印标题"""
    print("=" * 60)
    print("🎮 Joy-Con 手柄参数实时监控")
    print("=" * 60)
    print("按 Ctrl+C 退出程序")
    print("-" * 60)

def print_battery_status(battery_data, joycon_name):
    """打印电池状态"""
    if battery_data:
        level = battery_data.get('level', 0)
        charging = battery_data.get('charging', 0)
        
        # 电池电量显示
        battery_bars = "█" * level + "░" * (4 - level)
        charging_icon = "⚡" if charging else ""
        
        print(f"🔋 {joycon_name} 电池: [{battery_bars}] 电量:{level}/4 {charging_icon}")

def print_button_status(buttons_data, joycon_name):
    """打印按钮状态"""
    if not buttons_data:
        return
    
    print(f"\n🎮 {joycon_name} 按钮状态:")
    
    # 左/右 Joy-Con 按钮
    for side in ['left', 'right']:
        if side in buttons_data:
            side_buttons = buttons_data[side]
            print(f"  {side.upper()}: ", end="")
            
            for button, value in side_buttons.items():
                status = "●" if value == 1 else "○"
                print(f"{button.upper()}:{status} ", end="")
            print()
    
    # 共享按钮
    if 'shared' in buttons_data:
        shared_buttons = buttons_data['shared']
        print(f"  共享: ", end="")
        for button, value in shared_buttons.items():
            status = "●" if value == 1 else "○"
            print(f"{button.upper()}:{status} ", end="")
        print()

def print_stick_status(sticks_data):
    """打印摇杆状态"""
    if not sticks_data:
        return
    
    print(f"\n🎯 摇杆位置:")
    for stick_side in ['left', 'right']:
        if stick_side in sticks_data:
            stick = sticks_data[stick_side]
            h = stick.get('horizontal', 0)
            v = stick.get('vertical', 0)
            
            # 计算摇杆位置百分比
            h_percent = (h / 4095) * 100 if h > 0 else 0
            v_percent = (v / 4095) * 100 if v > 0 else 0
            
            print(f"  {stick_side.upper()}: H={h:4d}({h_percent:5.1f}%) V={v:4d}({v_percent:5.1f}%)")

def print_sensor_data(sensor_data, sensor_name):
    """打印传感器数据"""
    if not sensor_data:
        print(f"\n📊 {sensor_name}: 无数据")
        return
    
    print(f"\n📊 {sensor_name}:")
    for axis in ['x', 'y', 'z']:
        if axis in sensor_data:
            value = sensor_data[axis]
            # 检查数据是否有效（非零或非None）
            if value is not None and value != 0:
                print(f"  {axis.upper()}: {value:8.2f}")
            else:
                print(f"  {axis.upper()}: {value:8.2f} (可能未校准)")
        else:
            print(f"  {axis.upper()}: 缺失数据")

def print_status(status_data, joycon_name):
    """打印完整状态"""
    print(f"\n{'='*20} {joycon_name} {'='*20}")
    
    # 电池状态
    if 'battery' in status_data:
        print_battery_status(status_data['battery'], joycon_name)
    
    # 按钮状态
    if 'buttons' in status_data:
        print_button_status(status_data['buttons'], joycon_name)
    
    # 摇杆状态
    if 'analog-sticks' in status_data:
        print_stick_status(status_data['analog-sticks'])
    
    # 加速度计
    if 'accel' in status_data:
        print_sensor_data(status_data['accel'], "加速度计")
    
    # 陀螺仪
    if 'gyro' in status_data:
        print_sensor_data(status_data['gyro'], "陀螺仪")
    else:
        print(f"\n📊 陀螺仪: 数据缺失 (可用键: {list(status_data.keys())})")

def main():
    """主函数"""
    clear_screen()
    print_header()
    
    # 连接 Joy-Con
    joycon_L = None
    joycon_R = None
    
    print("正在连接 Joy-Con...")
    
    # 连接左 Joy-Con
    try:
        joycon_id_L = get_L_id()
        if joycon_id_L and None not in joycon_id_L:
            joycon_L = JoyCon(*joycon_id_L)
            # 初始化陀螺仪校准
            try:
                joycon_L.set_gyro_calibration()
                joycon_L.set_accel_calibration()
                print("✅ 左 Joy-Con 连接成功 (传感器已校准)")
            except Exception as calib_e:
                print(f"✅ 左 Joy-Con 连接成功 (传感器校准失败: {calib_e})")
    except Exception as e:
        print(f"❌ 左 Joy-Con 连接失败: {e}")
    
    # 连接右 Joy-Con
    try:
        joycon_id_R = get_R_id()
        if joycon_id_R and None not in joycon_id_R:
            joycon_R = JoyCon(*joycon_id_R)
            # 初始化陀螺仪校准
            try:
                joycon_R.set_gyro_calibration()
                joycon_R.set_accel_calibration()
                print("✅ 右 Joy-Con 连接成功 (传感器已校准)")
            except Exception as calib_e:
                print(f"✅ 右 Joy-Con 连接成功 (传感器校准失败: {calib_e})")
    except Exception as e:
        print(f"❌ 右 Joy-Con 连接失败: {e}")
    
    if not joycon_L and not joycon_R:
        print("❌ 未检测到任何 Joy-Con 设备")
        return
    
    print("开始监控 Joy-Con 状态...")
    print("等待传感器初始化...")
    time.sleep(2)  # 等待2秒让传感器初始化
    print("-" * 60)
    
    try:
        while True:
            clear_screen()
            print_header()
            
            # 读取左 Joy-Con
            if joycon_L:
                try:
                    status_L = joycon_L.get_status()
                    print_status(status_L, "左 Joy-Con")
                except Exception as e:
                    print(f"❌ 左 Joy-Con 读取失败: {e}")
            
            # 读取右 Joy-Con
            if joycon_R:
                try:
                    status_R = joycon_R.get_status()
                    print_status(status_R, "右 Joy-Con")
                except Exception as e:
                    print(f"❌ 右 Joy-Con 读取失败: {e}")
            
            # 显示时间戳
            print(f"\n⏰ 更新时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
            print("-" * 60)
            
            time.sleep(1/60)  # 每秒更新60次
            
    except KeyboardInterrupt:
        print("\n\n程序已退出")
    finally:
        print("程序已完全退出")

if __name__ == "__main__":
    main() 